library(MASS)
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✔ ggplot2 3.3.6 ✔ purrr 0.3.4
✔ tibble 3.1.7 ✔ dplyr 1.0.9
✔ tidyr 1.2.0 ✔ stringr 1.4.0
✔ readr 2.1.2 ✔ forcats 0.5.1
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
✖ dplyr::select() masks MASS::select()
library(ggplot2)
library(readr)
library(viridis)
Loading required package: viridisLite
library(ggfortify)
library(bbmle) #For ICtab
Loading required package: stats4
Attaching package: ‘bbmle’
The following object is masked from ‘package:dplyr’:
slice
library(car)
Loading required package: carData
Attaching package: ‘car’
The following object is masked from ‘package:dplyr’:
recode
The following object is masked from ‘package:purrr’:
some
library(emmeans)
round_any <- function(x, accuracy, f=round){f(x/ accuracy) * accuracy}
round_any <- function(x, accuracy, f=round){f(x/ accuracy) * accuracy}
# trial_types <- c("none","brood","worker","queen","all")
#
# for (t in trial_types){
# bee_param_df <- list.files(path=paste0("hive_data/heat_",t,"/"), full.names = TRUE) %>%
# lapply(read_csv, show_col_types = FALSE) %>%
# bind_rows %>%
# mutate(filenames = list.files(path=paste0("hive_data/heat_",t,"/"), full.names = TRUE))
#
# write.csv(bee_param_df,paste0("bee_data_isaac_heat_",t,".csv"),row.names = FALSE)
# }
What these all mean: n = queen cells per hour rb = brood radius rn =
necter radius w = total daily honey pph = pollen ratio ph = honey
consumption ratio pp = pollen consumption ratio k = consumption
probability value
broodMetric = average number of brood surrounding other brood
pollenRing = average min distance between honey and brood
brood_bee_param <- read.csv("bee_data_isaac_heat_brood.csv") %>% mutate(type = "Brood") %>% mutate(wha = 0, qha = 0)
worker_bee_param <- read.csv("bee_data_isaac_heat_worker.csv") %>% mutate(type = "Worker") %>% mutate(bhd = 0, qha = 0)
queen_bee_param <- read.csv("bee_data_isaac_heat_queen.csv") %>% mutate(type = "Queen") %>% mutate(bhd = 0, wha = 0)
none_bee_param <- read.csv("bee_data_isaac_heat_none.csv") %>% mutate(type = "None") %>% mutate(bhd = 0,wha = 0, qha = 0)
all_bee_param <- read.csv("bee_data_isaac_heat_all.csv") %>% mutate(type = "All")
bee_heat_param_df <- rbind(brood_bee_param,worker_bee_param) %>% rbind(.,queen_bee_param) %>% rbind(.,all_bee_param) %>% rbind(.,none_bee_param)
ggplot(bee_heat_param_df, aes(x = type, y = pBroodHeat))+
geom_boxplot()+
theme_classic()

heat_glm <- glm(pBroodHeat ~ 0 + type, data = bee_heat_param_df)
contrast(emmeans(heat_glm, "type"), "pairwise", adjust = "Tukey")
contrast estimate SE df t.ratio p.value
All - Brood -0.0545 0.00819 3835 -6.650 <.0001
All - None -0.4391 0.00819 3835 -53.600 <.0001
All - Queen -0.2398 0.00819 3835 -29.271 <.0001
All - Worker -0.3607 0.00819 3835 -44.021 <.0001
Brood - None -0.3847 0.00772 3835 -49.798 <.0001
Brood - Queen -0.1853 0.00772 3835 -23.993 <.0001
Brood - Worker -0.3062 0.00772 3835 -39.638 <.0001
None - Queen 0.1993 0.00772 3835 25.805 <.0001
None - Worker 0.0785 0.00772 3835 10.160 <.0001
Queen - Worker -0.1208 0.00772 3835 -15.645 <.0001
P value adjustment: tukey method for comparing a family of 5 estimates
ggplot(all_bee_param %>% na.omit(), aes(x = qha, y = bhd, color = pBroodHeat))+
geom_point()+
scale_color_viridis()+
theme_classic()

rounded_all_bee_param <- all_bee_param %>% mutate(rounded_qha = round_any(qha, 0.25),
rounded_bhd = round_any(bhd, 0.25))
ggplot(rounded_all_bee_param %>% na.omit(), aes(x = rounded_qha, y = rounded_bhd, z = pBroodHeat))+
geom_contour_filled()+
theme_classic()

NA
NA
Looking at correlation between heat parameter and brood in the
place
ggplot(bee_heat_param_df %>% filter(bhd > 0), aes(x = bhd, y = pBroodHeat))+
geom_point()+
geom_smooth(method = 'glm', formula = 'y ~ x')+
theme_classic()

cor.test((bee_heat_param_df %>% filter(bhd > 0))$bhd,(bee_heat_param_df %>% filter(bhd > 0))$pBroodHeat)
Pearson's product-moment correlation
data: (bee_heat_param_df %>% filter(bhd > 0))$bhd and (bee_heat_param_df %>% filter(bhd > 0))$pBroodHeat
t = -32.341, df = 1438, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.6778413 -0.6179628
sample estimates:
cor
-0.6489056
ggplot(bee_heat_param_df %>% filter(qha > 0), aes(x = qha, y = pBroodHeat))+
geom_point()+
geom_smooth(method = 'glm', formula = 'y ~ x')+
theme_classic()

cor.test((bee_heat_param_df %>% filter(qha > 0))$qha,(bee_heat_param_df %>% filter(qha > 0))$pBroodHeat)
Pearson's product-moment correlation
data: (bee_heat_param_df %>% filter(qha > 0))$qha and (bee_heat_param_df %>% filter(qha > 0))$pBroodHeat
t = -27.375, df = 1438, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.6182844 -0.5503031
sample estimates:
cor
-0.5853215
ggplot(bee_heat_param_df %>% filter(wha > 0), aes(x = wha, y = pBroodHeat))+
geom_point()+
geom_smooth(method = 'glm', formula = 'y ~ x')+
theme_classic()

cor.test((bee_heat_param_df %>% filter(wha > 0))$wha,(bee_heat_param_df %>% filter(wha > 0))$pBroodHeat)
Pearson's product-moment correlation
data: (bee_heat_param_df %>% filter(wha > 0))$wha and (bee_heat_param_df %>% filter(wha > 0))$pBroodHeat
t = -5.9184, df = 1438, p-value = 4.058e-09
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.2042354 -0.1033708
sample estimates:
cor
-0.1542049
Let’s make some stepwise models! Just with the all data for now so
there aren’t so many zeroes
hive_pca <- prcomp(bee_heat_param_df %>% select(-c(...1, trial_n, type, days, n,
pBrood, pPollen, pHoney, pEmpty,
pBroodHeat, pPollenHeat, pHoneyHeat, pEmptyHeat,
broodMetric,pollenRing)),
center = TRUE,scale. = TRUE)
Error in colMeans(x, na.rm = TRUE) : 'x' must be numeric
heat_brood_glm <- glm(pBroodHeat ~ ., data = all_bee_param %>% dplyr::select(-c(...1, trial_n, type, days, n,
pBrood, pPollen, pHoney, pEmpty,
pPollenHeat, pHoneyHeat, pEmptyHeat,
broodMetric,pollenRing)))
stepped_model <- stepAIC(heat_brood_glm, direction = "both")
Start: AIC=-1644.08
pBroodHeat ~ rb + rn + w + pph + ph + pp + k + bhd + wha + qha
Df Deviance AIC
- wha 1 2.7657 -1646.0
- rb 1 2.7660 -1646.0
- k 1 2.7710 -1644.8
- pph 1 2.7733 -1644.3
<none> 2.7655 -1644.1
- rn 1 2.7757 -1643.7
- w 1 2.7808 -1642.5
- ph 1 2.7828 -1642.1
- pp 1 2.8025 -1637.6
- qha 1 3.6132 -1475.0
- bhd 1 4.1686 -1383.5
Step: AIC=-1646.02
pBroodHeat ~ rb + rn + w + pph + ph + pp + k + bhd + qha
Df Deviance AIC
- rb 1 2.7662 -1647.9
- k 1 2.7711 -1646.8
- pph 1 2.7739 -1646.2
<none> 2.7657 -1646.0
- rn 1 2.7759 -1645.7
- w 1 2.7812 -1644.5
+ wha 1 2.7655 -1644.1
- ph 1 2.7832 -1644.0
- pp 1 2.8028 -1639.5
- qha 1 3.6153 -1476.6
- bhd 1 4.1692 -1385.3
Step: AIC=-1647.9
pBroodHeat ~ rn + w + pph + ph + pp + k + bhd + qha
Df Deviance AIC
- k 1 2.7714 -1648.7
- pph 1 2.7743 -1648.0
<none> 2.7662 -1647.9
- rn 1 2.7764 -1647.5
- w 1 2.7821 -1646.2
+ rb 1 2.7657 -1646.0
- ph 1 2.7833 -1646.0
+ wha 1 2.7660 -1646.0
- pp 1 2.8029 -1641.5
- qha 1 3.6153 -1478.6
- bhd 1 4.1692 -1387.3
Step: AIC=-1648.71
pBroodHeat ~ rn + w + pph + ph + pp + bhd + qha
Df Deviance AIC
<none> 2.7714 -1648.7
- pph 1 2.7802 -1648.7
- rn 1 2.7807 -1648.6
+ k 1 2.7662 -1647.9
- ph 1 2.7879 -1646.9
+ rb 1 2.7711 -1646.8
+ wha 1 2.7713 -1646.7
- w 1 2.7888 -1646.7
- pp 1 2.8093 -1642.0
- qha 1 3.6258 -1478.7
- bhd 1 4.1708 -1389.1
Anova(stepped_model)
Analysis of Deviance Table (Type II tests)
Response: pBroodHeat
LR Chisq Df Pr(>Chisq)
rn 2.11 1 0.146522
w 3.96 1 0.046605 *
pph 2.00 1 0.157613
ph 3.77 1 0.052131 .
pp 8.63 1 0.003303 **
bhd 319.12 1 < 2.2e-16 ***
qha 194.83 1 < 2.2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(all_bee_param, aes(bhd, pBroodHeat, color = pBroodHeat))+
geom_point()+
scale_color_viridis()+
theme_classic()

ggplot(all_bee_param, aes(qha, pBroodHeat, color = pBroodHeat))+
geom_point()+
scale_color_viridis()+
theme_classic()

now let’s see about the order of those models
bhd_m <- glm(pBroodHeat ~ bhd, data = all_bee_param)
bhd_2_m <- glm(pBroodHeat ~ poly(bhd,2), data = all_bee_param)
bhd_3_m <- glm(pBroodHeat ~ poly(bhd,3), data = all_bee_param)
bhd_ln_m <- glm(pBroodHeat ~ log(bhd), data = all_bee_param)
ICtab(bhd_m,bhd_2_m,bhd_3_m,bhd_ln_m)
dAIC df
bhd_2_m 0.0 4
bhd_3_m 1.3 5
bhd_ln_m 15.3 3
bhd_m 43.6 3
ggplot(all_bee_param, aes(bhd, pBroodHeat, color = pBroodHeat))+
geom_point()+
geom_smooth(method = "glm", formula = "y ~ poly(x,2)", se = FALSE) +
scale_color_viridis()+
theme_classic()

qha_m <- glm(pBroodHeat ~ qha, data = all_bee_param)
qha_2_m <- glm(pBroodHeat ~ poly(qha,2), data = all_bee_param)
qha_3_m <- glm(pBroodHeat ~ poly(qha,3), data = all_bee_param)
qha_ln_m <- glm(pBroodHeat ~ log(qha), data = all_bee_param)
ICtab(qha_m,qha_2_m,qha_3_m,qha_ln_m)
dAIC df
qha_m 0.0 3
qha_3_m 0.3 5
qha_2_m 1.9 4
qha_ln_m 31.9 3
ggplot(all_bee_param, aes(qha, pBroodHeat, color = pBroodHeat))+
geom_point()+
geom_smooth(method = "glm", formula = "y ~ x", se = FALSE) +
scale_color_viridis()+
theme_classic()

From the none data, looking at the good ones. The pollen ring metric
seems a bit off
Step AIC to see what predicts good or bad
Anova(stepped_good_model)
Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
Analysis of Deviance Table (Type II tests)
Response: good_or_bad
LR Chisq Df Pr(>Chisq)
rn 22.3956 1 2.219e-06 ***
k 7.7241 1 0.005449 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(none_bee_param_good_bad, aes(x = n, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = rb, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = rn, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = w, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = pph, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = ph, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = pp, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

ggplot(none_bee_param_good_bad, aes(x = k, fill = good_or_bad))+
geom_histogram(bins = 10)+
theme_classic()

OLDER CODE, looking at model type, we decided on M2 ####
rand_bee_param <- read.csv("bee_data_isaac_rand.csv") %>% mutate(type = "Rand")
m1_bee_param <- read.csv("bee_data_isaac_m1.csv") %>% mutate(type = "M1") %>% select(-trial_n)
m2_bee_param <- read.csv("bee_data_isaac_m2.csv") %>% mutate(type = "M2") %>% select(-trial_n)
m2E_bee_param <- read.csv("bee_data_isaac_m2_empty.csv") %>% mutate(type = "M2E") %>% select(-trial_n)
m2K_bee_param <- read.csv("bee_data_isaac_m2_katie.csv") %>% mutate(type = "M2K") %>% select(-trial_n)
bee_param_df <- rbind(m1_bee_param,m2_bee_param) %>% rbind(.,rand_bee_param) %>% rbind(.,m2E_bee_param) %>% rbind(.,m2K_bee_param)
bee_param_df_perc <- bee_param_df %>% select(c(type,pBrood,pHoney,pPollen,pEmpty)) %>%
pivot_longer(c(pBrood,pHoney,pPollen,pEmpty))
ggplot(bee_param_df, aes(x = broodMetric, y = pollenRing, color = type))+
geom_point(alpha = 0.25)+
ylim(0,16)+
xlim(0,6)+
theme_classic()
ggplot(bee_param_df_perc, aes(x = type, y = value, fill = name))+
geom_boxplot()+
theme_classic()
ggplot(m1_bee_param, aes(x = pPollen, y = pph))+
geom_point()+
theme_classic()
broodMetricGLM_m0 <- glm(broodMetric ~ 1, data = m2_bee_param)
broodMetricGLM_m1 <- glm(broodMetric ~ n + rb + rn + w + pph + ph + pp + k, data = m2_bee_param)
broodMetricGLM_step <- step(broodMetricGLM_m0, direction = "both", scope = formula(broodMetricGLM_m1), trace = 0)
summary(broodMetricGLM_step)
pollenRingGLM_m0 <- glm(pollenRing ~ 1, data = m2_bee_param)
pollenRingGLM_m1 <- glm(pollenRing ~ n + rb + rn + w + pph + ph + pp + k, data = m2_bee_param)
pollenRingGLM_step <- step(pollenRingGLM_m0, direction = "both", scope = formula(pollenRingGLM_m1), trace = 0)
summary(pollenRingGLM_step)
queen_pos_df <- read.csv("queen_pos_data_28_5.csv")
queen_pos_df_heatmap <- queen_pos_df %>% mutate(QueenXRound = round_any(QueenX,5),
QueenYRound = round_any(QueenY,5)) %>%
group_by(QueenXRound,QueenYRound) %>%
summarise(meanAngleMoved = mean(AngleMoved),
count = n())
`summarise()` has grouped output by 'QueenXRound'. You can override using the `.groups` argument.
ggplot(queen_pos_df, aes(x = QueenX, y = QueenY))+
geom_path()+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df, aes(x = QueenX, y = QueenY, color = Dist2Heat))+
geom_point()+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df, aes(x = QueenX, y = QueenY, color = cos(AngleOppHeat)))+
geom_point()+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df, aes(x = QueenX, y = QueenY, color = sin(AngleOppHeat)))+
geom_point()+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df_heatmap, aes(x = QueenXRound, y = QueenYRound, color = cos(meanAngleMoved)))+
geom_point(size = 5)+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df_heatmap, aes(x = QueenXRound, y = QueenYRound, color = sin(meanAngleMoved)))+
geom_point(size = 5)+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

ggplot(queen_pos_df_heatmap, aes(x = QueenXRound, y = QueenYRound, color = count))+
geom_point(size = 5)+
geom_point(aes(x=11,y=48.5),colour="red") +
scale_color_viridis() +
theme_classic()

LS0tCnRpdGxlOiAiSGl2ZSBQYXJhbWV0ZXIgQW5hbHlzaXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIExvYWQgUGFja2FnZXN9CmxpYnJhcnkoTUFTUykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShyZWFkcikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGdnZm9ydGlmeSkKbGlicmFyeShiYm1sZSkgI0ZvciBJQ3RhYgpsaWJyYXJ5KGNhcikKbGlicmFyeShlbW1lYW5zKQoKIApyb3VuZF9hbnkgPC0gZnVuY3Rpb24oeCwgYWNjdXJhY3ksIGY9cm91bmQpe2YoeC8gYWNjdXJhY3kpICogYWNjdXJhY3l9CgpgYGAKCmBgYHtyfQoKcm91bmRfYW55IDwtIGZ1bmN0aW9uKHgsIGFjY3VyYWN5LCBmPXJvdW5kKXtmKHgvIGFjY3VyYWN5KSAqIGFjY3VyYWN5fQoKYGBgCgoKYGBge3IgUmVhZCBpbiBEYXRhfQojIHRyaWFsX3R5cGVzIDwtIGMoIm5vbmUiLCJicm9vZCIsIndvcmtlciIsInF1ZWVuIiwiYWxsIikKIyAKIyBmb3IgKHQgaW4gdHJpYWxfdHlwZXMpewojICAgYmVlX3BhcmFtX2RmIDwtIGxpc3QuZmlsZXMocGF0aD1wYXN0ZTAoImhpdmVfZGF0YS9oZWF0XyIsdCwiLyIpLCBmdWxsLm5hbWVzID0gVFJVRSkgJT4lCiMgICAgICAgICAgICAgICAgIGxhcHBseShyZWFkX2Nzdiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgJT4lCiMgICAgICAgICAgICAgICAgIGJpbmRfcm93cyAlPiUKIyAgICAgICAgICAgICAgICAgbXV0YXRlKGZpbGVuYW1lcyA9IGxpc3QuZmlsZXMocGF0aD1wYXN0ZTAoImhpdmVfZGF0YS9oZWF0XyIsdCwiLyIpLCBmdWxsLm5hbWVzID0gVFJVRSkpCiMgCiMgICB3cml0ZS5jc3YoYmVlX3BhcmFtX2RmLHBhc3RlMCgiYmVlX2RhdGFfaXNhYWNfaGVhdF8iLHQsIi5jc3YiKSxyb3cubmFtZXMgPSBGQUxTRSkKIyB9CgpgYGAKCldoYXQgdGhlc2UgYWxsIG1lYW46Cm4gPSBxdWVlbiBjZWxscyBwZXIgaG91cgpyYiA9IGJyb29kIHJhZGl1cwpybiA9IG5lY3RlciByYWRpdXMKdyA9IHRvdGFsIGRhaWx5IGhvbmV5CnBwaCA9IHBvbGxlbiByYXRpbwpwaCA9IGhvbmV5IGNvbnN1bXB0aW9uIHJhdGlvCnBwID0gcG9sbGVuIGNvbnN1bXB0aW9uIHJhdGlvCmsgPSBjb25zdW1wdGlvbiBwcm9iYWJpbGl0eSB2YWx1ZQoKYnJvb2RNZXRyaWMgPSBhdmVyYWdlIG51bWJlciBvZiBicm9vZCBzdXJyb3VuZGluZyBvdGhlciBicm9vZApwb2xsZW5SaW5nID0gYXZlcmFnZSBtaW4gZGlzdGFuY2UgYmV0d2VlbiBob25leSBhbmQgYnJvb2QKCmBgYHtyfQpicm9vZF9iZWVfcGFyYW0gPC0gcmVhZC5jc3YoImJlZV9kYXRhX2lzYWFjX2hlYXRfYnJvb2QuY3N2IikgJT4lIG11dGF0ZSh0eXBlID0gIkJyb29kIikgJT4lIG11dGF0ZSh3aGEgPSAwLCBxaGEgPSAwKQp3b3JrZXJfYmVlX3BhcmFtIDwtIHJlYWQuY3N2KCJiZWVfZGF0YV9pc2FhY19oZWF0X3dvcmtlci5jc3YiKSAlPiUgbXV0YXRlKHR5cGUgPSAiV29ya2VyIikgJT4lIG11dGF0ZShiaGQgPSAwLCBxaGEgPSAwKQpxdWVlbl9iZWVfcGFyYW0gPC0gcmVhZC5jc3YoImJlZV9kYXRhX2lzYWFjX2hlYXRfcXVlZW4uY3N2IikgJT4lIG11dGF0ZSh0eXBlID0gIlF1ZWVuIikgJT4lIG11dGF0ZShiaGQgPSAwLCB3aGEgPSAwKQpub25lX2JlZV9wYXJhbSA8LSByZWFkLmNzdigiYmVlX2RhdGFfaXNhYWNfaGVhdF9ub25lLmNzdiIpICU+JSBtdXRhdGUodHlwZSA9ICJOb25lIikgJT4lIG11dGF0ZShiaGQgPSAwLHdoYSA9IDAsIHFoYSA9IDApCmFsbF9iZWVfcGFyYW0gPC0gcmVhZC5jc3YoImJlZV9kYXRhX2lzYWFjX2hlYXRfYWxsLmNzdiIpICU+JSBtdXRhdGUodHlwZSA9ICJBbGwiKQoKYmVlX2hlYXRfcGFyYW1fZGYgPC0gcmJpbmQoYnJvb2RfYmVlX3BhcmFtLHdvcmtlcl9iZWVfcGFyYW0pICU+JSByYmluZCguLHF1ZWVuX2JlZV9wYXJhbSkgJT4lIHJiaW5kKC4sYWxsX2JlZV9wYXJhbSkgCmBgYAoKCmBgYHtyfQpnZ3Bsb3QoYmVlX2hlYXRfcGFyYW1fZGYsIGFlcyh4ID0gdHlwZSwgeSA9IHBCcm9vZEhlYXQpKSsKICBnZW9tX2JveHBsb3QoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmhlYXRfZ2xtIDwtIGdsbShwQnJvb2RIZWF0IH4gMCArIHR5cGUsIGRhdGEgPSBiZWVfaGVhdF9wYXJhbV9kZikKCmNvbnRyYXN0KGVtbWVhbnMoaGVhdF9nbG0sICJ0eXBlIiksICJwYWlyd2lzZSIsIGFkanVzdCA9ICJUdWtleSIpCgpgYGAKCgpgYGB7cn0KCmdncGxvdChhbGxfYmVlX3BhcmFtICU+JSBuYS5vbWl0KCksIGFlcyh4ID0gcWhhLCB5ID0gYmhkLCBjb2xvciA9IHBCcm9vZEhlYXQpKSsKICBnZW9tX3BvaW50KCkrCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpKwogIHRoZW1lX2NsYXNzaWMoKQoKcm91bmRlZF9hbGxfYmVlX3BhcmFtIDwtIGFsbF9iZWVfcGFyYW0gJT4lIG11dGF0ZShyb3VuZGVkX3FoYSA9IHJvdW5kX2FueShxaGEsIDAuMjUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmRlZF9iaGQgPSByb3VuZF9hbnkoYmhkLCAwLjI1KSkKCmdncGxvdChyb3VuZGVkX2FsbF9iZWVfcGFyYW0gJT4lIG5hLm9taXQoKSwgYWVzKHggPSByb3VuZGVkX3FoYSwgeSA9IHJvdW5kZWRfYmhkLCB6ID0gcEJyb29kSGVhdCkpKwogIGdlb21fY29udG91cl9maWxsZWQoKSsKICB0aGVtZV9jbGFzc2ljKCkKCgpgYGAKCgoKCmBgYHtyfQoKZ2dwbG90KGJlZV9oZWF0X3BhcmFtX2RmICU+JSBuYS5vbWl0KCksIGFlcyh4ID0gYnJvb2RNZXRyaWMsIHkgPSBwb2xsZW5SaW5nLCBjb2xvciA9IHBIb25leSkpKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjEpKwogIGdlb21fcmVjdChhZXMoeG1pbiA9IDUsIHhtYXggPSA2LCB5bWluID0gMTIsIHltYXggPSAzMCksIGZpbGwgPSBOQSkrCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpKwogIHRoZW1lX2NsYXNzaWMoKQoKbWF4KGJlZV9oZWF0X3BhcmFtX2RmJHBvbGxlblJpbmcpCgpiZWVfaGVhdF9wYXJhbV9kZiAlPiUgZmlsdGVyKGJyb29kTWV0cmljID49IDUgJiBwb2xsZW5SaW5nID49IDEwKQpgYGAKCgoKTG9va2luZyBhdCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGhlYXQgcGFyYW1ldGVyIGFuZCBicm9vZCBpbiB0aGUgcGxhY2UKCmBgYHtyfQpnZ3Bsb3QoYmVlX2hlYXRfcGFyYW1fZGYgJT4lIGZpbHRlcihiaGQgPiAwKSwgYWVzKHggPSBiaGQsIHkgPSBwQnJvb2RIZWF0KSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnbG0nLCBmb3JtdWxhID0gJ3kgfiB4JykrCiAgdGhlbWVfY2xhc3NpYygpCgpjb3IudGVzdCgoYmVlX2hlYXRfcGFyYW1fZGYgJT4lIGZpbHRlcihiaGQgPiAwKSkkYmhkLChiZWVfaGVhdF9wYXJhbV9kZiAlPiUgZmlsdGVyKGJoZCA+IDApKSRwQnJvb2RIZWF0KQoKZ2dwbG90KGJlZV9oZWF0X3BhcmFtX2RmICU+JSBmaWx0ZXIocWhhID4gMCksIGFlcyh4ID0gcWhhLCB5ID0gcEJyb29kSGVhdCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2xtJywgZm9ybXVsYSA9ICd5IH4geCcpKwogIHRoZW1lX2NsYXNzaWMoKQoKY29yLnRlc3QoKGJlZV9oZWF0X3BhcmFtX2RmICU+JSBmaWx0ZXIocWhhID4gMCkpJHFoYSwoYmVlX2hlYXRfcGFyYW1fZGYgJT4lIGZpbHRlcihxaGEgPiAwKSkkcEJyb29kSGVhdCkKCmdncGxvdChiZWVfaGVhdF9wYXJhbV9kZiAlPiUgZmlsdGVyKHdoYSA+IDApLCBhZXMoeCA9IHdoYSwgeSA9IHBCcm9vZEhlYXQpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dsbScsIGZvcm11bGEgPSAneSB+IHgnKSsKICB0aGVtZV9jbGFzc2ljKCkKCmNvci50ZXN0KChiZWVfaGVhdF9wYXJhbV9kZiAlPiUgZmlsdGVyKHdoYSA+IDApKSR3aGEsKGJlZV9oZWF0X3BhcmFtX2RmICU+JSBmaWx0ZXIod2hhID4gMCkpJHBCcm9vZEhlYXQpCmBgYAoKTGV0J3MgbWFrZSBzb21lIHN0ZXB3aXNlIG1vZGVscyEgSnVzdCB3aXRoIHRoZSBhbGwgZGF0YSBmb3Igbm93IHNvIHRoZXJlIGFyZW4ndCBzbyBtYW55IHplcm9lcwoKYGBge3J9CgpoaXZlX3BjYSA8LSBwcmNvbXAoYmVlX2hlYXRfcGFyYW1fZGYgJT4lIHNlbGVjdCgtYyguLi4xLCB0cmlhbF9uLCB0eXBlLCBkYXlzLCBuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQnJvb2QsIHBQb2xsZW4sIHBIb25leSwgcEVtcHR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQnJvb2RIZWF0LCBwUG9sbGVuSGVhdCwgcEhvbmV5SGVhdCwgcEVtcHR5SGVhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJvb2RNZXRyaWMscG9sbGVuUmluZykpLAogICAgICAgICAgICAgICAgICAgY2VudGVyID0gVFJVRSxzY2FsZS4gPSBUUlVFKQpzdW1tYXJ5KGhpdmVfcGNhKQpoaXZlX3BjYSRyb3RhdGlvblssMToyXQoKYXV0b3Bsb3QoaGl2ZV9wY2EsIGNvbG91ciA9ICJwQnJvb2RIZWF0IiwgbG9hZGluZ3MgPSBUUlVFLCBsb2FkaW5ncy5sYWJlbCA9IFRSVUUsCiAgICAgICAgIGRhdGEgPSBiZWVfaGVhdF9wYXJhbV9kZikrCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KGJlZV9oZWF0X3BhcmFtX2RmLCBhZXMocFBvbGxlbiwgcEJyb29kSGVhdCkpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmdncGxvdChiZWVfaGVhdF9wYXJhbV9kZiwgYWVzKHdoYSwgcFBvbGxlbikpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmdncGxvdChiZWVfaGVhdF9wYXJhbV9kZiwgYWVzKHBwaCwgcHAsIGNvbG9yID0gcFBvbGxlbikpKwogIGdlb21fcG9pbnQoKSsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCkrCiAgdGhlbWVfY2xhc3NpYygpCmBgYAoKYGBge3J9CmhlYXRfYnJvb2RfZ2xtIDwtIGdsbShwQnJvb2RIZWF0IH4gLiwgZGF0YSA9IGFsbF9iZWVfcGFyYW0gJT4lIGRwbHlyOjpzZWxlY3QoLWMoLi4uMSwgdHJpYWxfbiwgdHlwZSwgZGF5cywgbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEJyb29kLCBwUG9sbGVuLCBwSG9uZXksIHBFbXB0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBvbGxlbkhlYXQsIHBIb25leUhlYXQsIHBFbXB0eUhlYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyb29kTWV0cmljLHBvbGxlblJpbmcpKSkKCnN0ZXBwZWRfbW9kZWwgPC0gc3RlcEFJQyhoZWF0X2Jyb29kX2dsbSwgZGlyZWN0aW9uID0gImJvdGgiKQoKCkFub3ZhKHN0ZXBwZWRfbW9kZWwpCgpnZ3Bsb3QoYWxsX2JlZV9wYXJhbSwgYWVzKGJoZCwgcEJyb29kSGVhdCwgY29sb3IgPSBwQnJvb2RIZWF0KSkrCiAgZ2VvbV9wb2ludCgpKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmdncGxvdChhbGxfYmVlX3BhcmFtLCBhZXMocWhhLCBwQnJvb2RIZWF0LCBjb2xvciA9IHBCcm9vZEhlYXQpKSsKICBnZW9tX3BvaW50KCkrCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpKwogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCm5vdyBsZXQncyBzZWUgYWJvdXQgdGhlIG9yZGVyIG9mIHRob3NlIG1vZGVscwoKYGBge3J9CgpiaGRfbSA8LSBnbG0ocEJyb29kSGVhdCB+IGJoZCwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCmJoZF8yX20gPC0gZ2xtKHBCcm9vZEhlYXQgfiBwb2x5KGJoZCwyKSwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCmJoZF8zX20gPC0gZ2xtKHBCcm9vZEhlYXQgfiBwb2x5KGJoZCwzKSwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCmJoZF9sbl9tIDwtIGdsbShwQnJvb2RIZWF0IH4gbG9nKGJoZCksIGRhdGEgPSBhbGxfYmVlX3BhcmFtKQoKSUN0YWIoYmhkX20sYmhkXzJfbSxiaGRfM19tLGJoZF9sbl9tKQoKZ2dwbG90KGFsbF9iZWVfcGFyYW0sIGFlcyhiaGQsIHBCcm9vZEhlYXQsIGNvbG9yID0gcEJyb29kSGVhdCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAiZ2xtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LDIpIiwgc2UgPSBGQUxTRSkgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoKSsKICB0aGVtZV9jbGFzc2ljKCkKCgpxaGFfbSA8LSBnbG0ocEJyb29kSGVhdCB+IHFoYSwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCnFoYV8yX20gPC0gZ2xtKHBCcm9vZEhlYXQgfiBwb2x5KHFoYSwyKSwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCnFoYV8zX20gPC0gZ2xtKHBCcm9vZEhlYXQgfiBwb2x5KHFoYSwzKSwgZGF0YSA9IGFsbF9iZWVfcGFyYW0pCnFoYV9sbl9tIDwtIGdsbShwQnJvb2RIZWF0IH4gbG9nKHFoYSksIGRhdGEgPSBhbGxfYmVlX3BhcmFtKQoKSUN0YWIocWhhX20scWhhXzJfbSxxaGFfM19tLHFoYV9sbl9tKQoKZ2dwbG90KGFsbF9iZWVfcGFyYW0sIGFlcyhxaGEsIHBCcm9vZEhlYXQsIGNvbG9yID0gcEJyb29kSGVhdCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAiZ2xtIiwgZm9ybXVsYSA9ICJ5IH4geCIsIHNlID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCkrCiAgdGhlbWVfY2xhc3NpYygpCgpgYGAKCkZyb20gdGhlIG5vbmUgZGF0YSwgbG9va2luZyBhdCB0aGUgZ29vZCBvbmVzLiBUaGUgcG9sbGVuIHJpbmcgbWV0cmljIHNlZW1zIGEgYml0IG9mZgpgYGB7cn0KCmdvb2RfaGl2ZXMgPC0gYygiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDAxMTFfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDEyNV9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwMjExX25vbmUucGRmIiwKICAgICAgICAgICAgICAgICJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDIxOV9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwMzMzX25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDA1MzBfbm9uZS5wZGYiLAogICAgICAgICAgICAgICAgImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwNjE5X25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDA3MDZfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDkyM19ub25lLnBkZiIsCiAgICAgICAgICAgICAgICAiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDA5Mjhfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMTQzMF9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAxNDMwX25vbmUucGRmIiwKICAgICAgICAgICAgICAgICJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMTcyMF9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAxOTE0X25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDE5MTVfbm9uZS5wZGYiLAogICAgICAgICAgICAgICAgImhpdmVwbG90XzAwNzIwX0QwMzBfVDAxOTM4X25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDIwMDFfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMjAyOF9ub25lLnBkZiIpCgpnb29kX2NzdnMgPC0gYygpCgpmb3IoaGl2ZSBpbiBnb29kX2hpdmVzKXsKICBudW1iZXIgPC0gc3Vic3RyaW5nKGhpdmUsMjIsMjYpCiAgCiAgZmlsZSA8LSBwYXN0ZTAoImhpdmVfZGF0YS9oZWF0X25vbmUvL0JlZWhpdmUgRGF0YSBPdXQgVHJpYWwgIixudW1iZXIsIl9ub25lLmNzdiIpCiAgCiAgZ29vZF9jc3ZzIDwtIGMoZmlsZSxnb29kX2NzdnMpCn0KCmJhZF9oaXZlcyA8LSBjKCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDEwOF9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwMTIyX25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDAyMDlfbm9uZS5wZGYiLAogICAgICAgICAgICAgICAiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDAyMThfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDIzNl9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwMzI4X25vbmUucGRmIiwKICAgICAgICAgICAgICAgImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwMzM1X25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDA0MjFfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDYxNF9ub25lLnBkZiIsCiAgICAgICAgICAgICAgICJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMDYzNV9ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAwNzExX25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDA5MzVfbm9uZS5wZGYiLAogICAgICAgICAgICAgICAiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDExMzdfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMTMxM19ub25lLnBkZiIsImhpdmVwbG90XzAwNzIwX0QwMzBfVDAxNTI1X25vbmUucGRmIiwKICAgICAgICAgICAgICAgImhpdmVwbG90XzAwNzIwX0QwMzBfVDAxNjIzX25vbmUucGRmIiwiaGl2ZXBsb3RfMDA3MjBfRDAzMF9UMDE3MjVfbm9uZS5wZGYiLCJoaXZlcGxvdF8wMDcyMF9EMDMwX1QwMTkyOF9ub25lLnBkZiIpCgpiYWRfY3N2cyA8LSBjKCkKCmZvcihoaXZlIGluIGJhZF9oaXZlcyl7CiAgbnVtYmVyIDwtIHN1YnN0cmluZyhoaXZlLDIyLDI2KQogIAogIGZpbGUgPC0gcGFzdGUwKCJoaXZlX2RhdGEvaGVhdF9ub25lLy9CZWVoaXZlIERhdGEgT3V0IFRyaWFsICIsbnVtYmVyLCJfbm9uZS5jc3YiKQogIAogIGJhZF9jc3ZzIDwtIGMoZmlsZSxiYWRfY3N2cykKfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKbm9uZV9iZWVfcGFyYW1fZ29vZF9iYWQgPC0gbm9uZV9iZWVfcGFyYW0gJT4lIGZpbHRlcihmaWxlbmFtZXMgJWluJSBnb29kX2NzdnMgfCBmaWxlbmFtZXMgJWluJSBiYWRfY3N2cykgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShib29sX2dvb2Rfb3JfYmFkID0gaWZlbHNlKGZpbGVuYW1lcyAlaW4lIGdvb2RfY3N2cywxLDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZF9vcl9iYWQgPSBpZmVsc2UoZmlsZW5hbWVzICVpbiUgZ29vZF9jc3ZzLCJHb29kIiwiQmFkIikpCm5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkCmBgYApTdGVwIEFJQyB0byBzZWUgd2hhdCBwcmVkaWN0cyBnb29kIG9yIGJhZAoKYGBge3J9Cgpnb29kX2hpdmVfZ2xtIDwtIGdsbShib29sX2dvb2Rfb3JfYmFkIH4gLiwgZGF0YSA9IG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkICU+JSBkcGx5cjo6c2VsZWN0KC1jKC4uLjEsIHRyaWFsX24sIHR5cGUsIGRheXMsIG4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCcm9vZCwgcFBvbGxlbiwgcEhvbmV5LCBwRW1wdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCcm9vZEhlYXQsIHBQb2xsZW5IZWF0LCBwSG9uZXlIZWF0LCBwRW1wdHlIZWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicm9vZE1ldHJpYyxwb2xsZW5SaW5nKSksCiAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9ICJiaW5vbWlhbCIpCgpzdGVwcGVkX2dvb2RfbW9kZWwgPC0gc3RlcEFJQyhnb29kX2hpdmVfZ2xtLCBkaXJlY3Rpb24gPSAiYm90aCIpCgoKQW5vdmEoc3RlcHBlZF9nb29kX21vZGVsKQoKCmBgYAoKYGBge3J9CmdncGxvdChub25lX2JlZV9wYXJhbV9nb29kX2JhZCwgYWVzKHggPSBuLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IHJiLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IHJuLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IHcsIGZpbGwgPSBnb29kX29yX2JhZCkpKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCkrCiAgdGhlbWVfY2xhc3NpYygpCgpnZ3Bsb3Qobm9uZV9iZWVfcGFyYW1fZ29vZF9iYWQsIGFlcyh4ID0gcHBoLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IHBoLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IHBwLCBmaWxsID0gZ29vZF9vcl9iYWQpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTApKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KG5vbmVfYmVlX3BhcmFtX2dvb2RfYmFkLCBhZXMoeCA9IGssIGZpbGwgPSBnb29kX29yX2JhZCkpKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCkrCiAgdGhlbWVfY2xhc3NpYygpCmBgYAoKIyMjIwpPTERFUiBDT0RFLCBsb29raW5nIGF0IG1vZGVsIHR5cGUsIHdlIGRlY2lkZWQgb24gTTIKIyMjIwoKCmBgYHtyfQpyYW5kX2JlZV9wYXJhbSA8LSByZWFkLmNzdigiYmVlX2RhdGFfaXNhYWNfcmFuZC5jc3YiKSAlPiUgbXV0YXRlKHR5cGUgPSAiUmFuZCIpCm0xX2JlZV9wYXJhbSA8LSByZWFkLmNzdigiYmVlX2RhdGFfaXNhYWNfbTEuY3N2IikgJT4lIG11dGF0ZSh0eXBlID0gIk0xIikgJT4lIHNlbGVjdCgtdHJpYWxfbikKbTJfYmVlX3BhcmFtIDwtIHJlYWQuY3N2KCJiZWVfZGF0YV9pc2FhY19tMi5jc3YiKSAlPiUgbXV0YXRlKHR5cGUgPSAiTTIiKSAlPiUgc2VsZWN0KC10cmlhbF9uKQptMkVfYmVlX3BhcmFtIDwtIHJlYWQuY3N2KCJiZWVfZGF0YV9pc2FhY19tMl9lbXB0eS5jc3YiKSAlPiUgbXV0YXRlKHR5cGUgPSAiTTJFIikgJT4lIHNlbGVjdCgtdHJpYWxfbikKbTJLX2JlZV9wYXJhbSA8LSByZWFkLmNzdigiYmVlX2RhdGFfaXNhYWNfbTJfa2F0aWUuY3N2IikgJT4lIG11dGF0ZSh0eXBlID0gIk0ySyIpICU+JSBzZWxlY3QoLXRyaWFsX24pCgpiZWVfcGFyYW1fZGYgPC0gcmJpbmQobTFfYmVlX3BhcmFtLG0yX2JlZV9wYXJhbSkgJT4lIHJiaW5kKC4scmFuZF9iZWVfcGFyYW0pICU+JSByYmluZCguLG0yRV9iZWVfcGFyYW0pICU+JSByYmluZCguLG0yS19iZWVfcGFyYW0pCmBgYAoKCmBgYHtyfQpiZWVfcGFyYW1fZGZfcGVyYyA8LSBiZWVfcGFyYW1fZGYgJT4lIHNlbGVjdChjKHR5cGUscEJyb29kLHBIb25leSxwUG9sbGVuLHBFbXB0eSkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdm90X2xvbmdlcihjKHBCcm9vZCxwSG9uZXkscFBvbGxlbixwRW1wdHkpKQpgYGAKCgpgYGB7ciBPdmVyYWxsIEJyb29kIGFuZCBQb2xsZW59CgpnZ3Bsb3QoYmVlX3BhcmFtX2RmLCBhZXMoeCA9IGJyb29kTWV0cmljLCB5ID0gcG9sbGVuUmluZywgY29sb3IgPSB0eXBlKSkrCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMjUpKwogIHlsaW0oMCwxNikrCiAgeGxpbSgwLDYpKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KGJlZV9wYXJhbV9kZl9wZXJjLCBhZXMoeCA9IHR5cGUsIHkgPSB2YWx1ZSwgZmlsbCA9IG5hbWUpKSsKICBnZW9tX2JveHBsb3QoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmdncGxvdChtMV9iZWVfcGFyYW0sIGFlcyh4ID0gcFBvbGxlbiwgeSA9IHBwaCkpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9jbGFzc2ljKCkKCmBgYAoKYGBge3IgQnJvb2QgTWV0cmljIEdMTXN9CmJyb29kTWV0cmljR0xNX20wIDwtIGdsbShicm9vZE1ldHJpYyB+IDEsIGRhdGEgPSBtMl9iZWVfcGFyYW0pCmJyb29kTWV0cmljR0xNX20xIDwtIGdsbShicm9vZE1ldHJpYyB+IG4gKyByYiArIHJuICsgdyArIHBwaCArIHBoICsgcHAgKyBrLCBkYXRhID0gbTJfYmVlX3BhcmFtKQpicm9vZE1ldHJpY0dMTV9zdGVwIDwtIHN0ZXAoYnJvb2RNZXRyaWNHTE1fbTAsIGRpcmVjdGlvbiA9ICJib3RoIiwgc2NvcGUgPSBmb3JtdWxhKGJyb29kTWV0cmljR0xNX20xKSwgdHJhY2UgPSAwKQoKc3VtbWFyeShicm9vZE1ldHJpY0dMTV9zdGVwKQpgYGAKCmBgYHtyIFBvbGxlbiBSaW5nIEdMTXN9CnBvbGxlblJpbmdHTE1fbTAgPC0gZ2xtKHBvbGxlblJpbmcgfiAxLCBkYXRhID0gbTJfYmVlX3BhcmFtKQpwb2xsZW5SaW5nR0xNX20xIDwtIGdsbShwb2xsZW5SaW5nIH4gbiArIHJiICsgcm4gKyB3ICsgcHBoICsgcGggKyBwcCArIGssIGRhdGEgPSBtMl9iZWVfcGFyYW0pCnBvbGxlblJpbmdHTE1fc3RlcCA8LSBzdGVwKHBvbGxlblJpbmdHTE1fbTAsIGRpcmVjdGlvbiA9ICJib3RoIiwgc2NvcGUgPSBmb3JtdWxhKHBvbGxlblJpbmdHTE1fbTEpLCB0cmFjZSA9IDApCgpzdW1tYXJ5KHBvbGxlblJpbmdHTE1fc3RlcCkKYGBgCgpgYGB7cn0KcXVlZW5fcG9zX2RmIDwtIHJlYWQuY3N2KCJxdWVlbl9wb3NfZGF0YV8yOF81LmNzdiIpCgpxdWVlbl9wb3NfZGZfaGVhdG1hcCA8LSBxdWVlbl9wb3NfZGYgJT4lIG11dGF0ZShRdWVlblhSb3VuZCA9IHJvdW5kX2FueShRdWVlblgsNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZWVuWVJvdW5kID0gcm91bmRfYW55KFF1ZWVuWSw1KSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieShRdWVlblhSb3VuZCxRdWVlbllSb3VuZCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UobWVhbkFuZ2xlTW92ZWQgPSBtZWFuKEFuZ2xlTW92ZWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gbigpKQoKYGBgCgoKYGBge3J9CmdncGxvdChxdWVlbl9wb3NfZGYsIGFlcyh4ID0gUXVlZW5YLCB5ID0gUXVlZW5ZKSkrCiAgZ2VvbV9wYXRoKCkrCiAgZ2VvbV9wb2ludChhZXMoeD0xMSx5PTQ4LjUpLGNvbG91cj0icmVkIikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoKSArCiAgdGhlbWVfY2xhc3NpYygpCgpnZ3Bsb3QocXVlZW5fcG9zX2RmLCBhZXMoeCA9IFF1ZWVuWCwgeSA9IFF1ZWVuWSwgY29sb3IgPSBEaXN0MkhlYXQpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9wb2ludChhZXMoeD0xMSx5PTQ4LjUpLGNvbG91cj0icmVkIikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoKSArCiAgdGhlbWVfY2xhc3NpYygpCgpnZ3Bsb3QocXVlZW5fcG9zX2RmLCBhZXMoeCA9IFF1ZWVuWCwgeSA9IFF1ZWVuWSwgY29sb3IgPSBjb3MoQW5nbGVPcHBIZWF0KSkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3BvaW50KGFlcyh4PTExLHk9NDguNSksY29sb3VyPSJyZWQiKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpICsKICB0aGVtZV9jbGFzc2ljKCkKCmdncGxvdChxdWVlbl9wb3NfZGYsIGFlcyh4ID0gUXVlZW5YLCB5ID0gUXVlZW5ZLCBjb2xvciA9IHNpbihBbmdsZU9wcEhlYXQpKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fcG9pbnQoYWVzKHg9MTEseT00OC41KSxjb2xvdXI9InJlZCIpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCkgKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KHF1ZWVuX3Bvc19kZl9oZWF0bWFwLCBhZXMoeCA9IFF1ZWVuWFJvdW5kLCB5ID0gUXVlZW5ZUm91bmQsIGNvbG9yID0gY29zKG1lYW5BbmdsZU1vdmVkKSkpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDUpKwogIGdlb21fcG9pbnQoYWVzKHg9MTEseT00OC41KSxjb2xvdXI9InJlZCIpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCkgKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KHF1ZWVuX3Bvc19kZl9oZWF0bWFwLCBhZXMoeCA9IFF1ZWVuWFJvdW5kLCB5ID0gUXVlZW5ZUm91bmQsIGNvbG9yID0gc2luKG1lYW5BbmdsZU1vdmVkKSkpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDUpKwogIGdlb21fcG9pbnQoYWVzKHg9MTEseT00OC41KSxjb2xvdXI9InJlZCIpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCkgKwogIHRoZW1lX2NsYXNzaWMoKQoKZ2dwbG90KHF1ZWVuX3Bvc19kZl9oZWF0bWFwLCBhZXMoeCA9IFF1ZWVuWFJvdW5kLCB5ID0gUXVlZW5ZUm91bmQsIGNvbG9yID0gY291bnQpKSsKICBnZW9tX3BvaW50KHNpemUgPSA1KSsKICBnZW9tX3BvaW50KGFlcyh4PTExLHk9NDguNSksY29sb3VyPSJyZWQiKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcygpICsKICB0aGVtZV9jbGFzc2ljKCkKYGBgCgoKCgoKCg==